package com.whl.cloud.filter;

import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.Charset;
import java.util.List;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.http.HttpStatus;
import org.springframework.stereotype.Component;
import org.springframework.util.StreamUtils;

import com.alibaba.fastjson.JSON;
import com.google.gson.Gson;
import com.netflix.util.Pair;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import com.whl.cloud.common.util.SessionUtil;
import com.whl.cloud.constant.SessionConstant;
import com.whl.cloud.constant.ZuulConstant;
import com.whl.cloud.model.LoginSession;
import com.whl.cloud.model.ResponseWapper;
import com.whl.cloud.model.SessionResult;

@Component
public class ResponseFilter extends ZuulFilter {
	@Autowired
	private Environment env;
	private static Log log = LogFactory.getLog(ResponseFilter.class);

	@Override
	public boolean shouldFilter() {
		return true;
	}

	@Override
	public Object run() {
		try {
			RequestContext curContext = RequestContext.getCurrentContext();
			String requestId = curContext.get("requestId").toString();
			// 302不做处理
			if (curContext.getResponseStatusCode() == HttpStatus.FOUND.value()) {
				return null;
			}
			
			// 出错的情况下,处理消息
			if (curContext.getResponseStatusCode() != HttpStatus.OK.value()) {
				ResponseWapper wapper = new ResponseWapper();
				InputStream stream = curContext.getResponseDataStream();
				if (stream != null) {
					try {
						String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));
						Object obj = JSON.parse(body);
						wapper.setCode(curContext.getResponseStatusCode());
						wapper.setData(obj);
						log.error("requestId = " + requestId + "\n" + body);
					} catch (IOException e) {
						log.error("requestId = " + requestId, e);
					}
				} else {
					Throwable e = curContext.getThrowable();
					wapper.setCode(curContext.getResponseStatusCode());
					wapper.setData(e.getMessage());
					log.error("requestId = " + requestId, e);
				}
				curContext.getResponse().setContentType("application/json; charset=utf-8");
				String wapperJSON = JSON.toJSONString(wapper);
				RequestContext.getCurrentContext().setResponseBody(wapperJSON);
				curContext.setResponseStatusCode(200);
				return null;
			}
			
			if (curContext.getResponseStatusCode() == HttpStatus.OK.value()) {
				// 过滤文件类
				List<Pair<String, String>> pairList = curContext.getOriginResponseHeaders();
				boolean isFile = pairList.stream().filter(pair -> ("Content-Disposition").equals(pair.first())).findAny()
						.isPresent();
				if (isFile == true) {
					return null;
				}

				InputStream stream = curContext.getResponseDataStream();
				String body = StreamUtils.copyToString(stream, Charset.forName("UTF-8"));

				// 登入
				if (curContext.getRequest().getServletPath().endsWith("login")) {
					LoginSession loginSession = new Gson().fromJson(body, LoginSession.class);
					SessionResult sessionResult = SessionUtil.initSession(loginSession,
							env.getProperty("session.timeout", Integer.class));
					SessionUtil.createCookie(curContext.getRequest(), curContext.getResponse(),
							SessionConstant.ACCESS_TOKEN, sessionResult.getAccessToken());
				}

				// 登出
				if (curContext.getRequest().getServletPath().endsWith("logout")) {
					SessionUtil.removeSession();
					SessionUtil.destroyCookie(curContext.getRequest(), curContext.getResponse(),
							SessionConstant.ACCESS_TOKEN);
				}

				ResponseWapper wapper = new ResponseWapper();
				wapper.setCode(200);
				Object obj = JSON.parse(body);
				wapper.setData(obj);
				String wapperJSON = JSON.toJSONString(wapper);
				if (log.isInfoEnabled()) {
					log.info("requestId = " + requestId + "\n" + wapperJSON);
				}
				curContext.getResponse().setContentType("application/json; charset=utf-8");
				RequestContext.getCurrentContext().setResponseBody(wapperJSON);
			}
			return null;
		} catch (IOException e) {
			e.printStackTrace();
		} finally {
			SessionUtil.destoryLocalSessionHolder();
		}
		return null;
		
	}
	
	
	

	@Override
	public String filterType() {
		return ZuulConstant.FILTER_TYPE_POST;
	}

	@Override
	public int filterOrder() {
		return 1;
	}

}
